<?php
include_once('dao_sn.php');
include_once('dao_common.php');
include_once('../../config/dao.cfg.php');
include_once('dao_logfilter.php');

define('DAO_LOG_DEBUG', 4);
define('DAO_LOG_INFO', 3);
define('DAO_LOG_RUN', 2);
define('DAO_LOG_ERROR', 1);

error_reporting(E_ERROR);

class	DAO_Log
{
	static $crlf=CRLF;
	public static  $level_file=array(1=>'error',2=>'info',4=>'debug');
	static public  $level_names=array(1=>'ERR',2=>'INFO',4=>'DBG');
	public static  $curr_module='dao';

	public static function get_log_file($module_setting,$level)
	{
		$file = self::$level_file[$level];
		$path = rtrim($module_setting['path'],"\\");
		$path = rtrim($module_setting['path'],'/');
		return $path.'/'.$module_setting['name'].'_'.$file.date('Ymd').'.log';
	}
	
	public static function  logdbg($msg)
	{
		echo $msg."\r\n";
	}
	
	public static function &get_setting($module)
	{
		global $log_setting;
		if(strlen($module)==0)
		{
			$module='dao';
		}
		return $log_setting[$module];
	}

	public static function set_max($module='dao')
	{
		global $log_setting;
		if(strlen(self::$curr_module))
		{
			$module= self::$curr_module;
		}
		$log_setting[$module]['level']=4;
		$log_setting[$module]['stdout']=true;
	}
	
	public static function set_min($module='dao')
	{
		global $log_setting;
		if(strlen(self::$curr_module))
		{
			$module= self::$curr_module;
		}
		$log_setting[$module]['level']=1;
		$log_setting[$module]["stdout"]=false;
	}

	public static function get_log_time($full_date=0)
	{
		if($full_date==1)
		{
			$format = 'Y-m-d H:i:s';
		}
		else
		{
			$format = 'H:i:s';
		}
		list($usec, $sec) = explode(" ", microtime());
		$usec =sprintf("%03d", (int)($usec*1000));
		return date ($format).'.'.$usec;
	}
	
	public static function get_trace(&$trace,$depth)
	{
		if(!isset($trace))
		{
			return ;
		}
		$trace_msg='';
		if(sizeof($trace_msg)>0)
		{
			$trace_msg =self::$crlf;
		}
		for($i=0;$i<$depth&&$i<sizeof($trace);$i++)
		{
			$trace_msg =$trace_msg ."\t". $trace[$i]['file'].':'.$trace[$i]['function'].':'.$trace[$i]['line'];
			$args=$trace[$i]['args'];
			//详细参数
			if(isset($args)&&false/*不记录参数*/)
			{   
				//class类型不能强制转换到string
				foreach($args as $key=>$value)
				{
					if(is_object($value)){$value=get_class($value);}
					$trace_msg = $trace_msg.",".$key."=>".strval($value);
				}
			}
			$trace_msg = $trace_msg.CRLF;
		}
		return $trace_msg;
	}

	public static function log_implement($level,$message,$module,$trace=NULL,$trace_layer=3)
	{

		global $log_setting;
		if(strlen($module)==0)
		{
			$module=self::$curr_module;
		}
		if(strlen($module)==0)
		{
			$module='dao';
		}
		$module_setting=$log_setting[$module];
		if(!isset($module_setting))
		{
			return ;
		}
		if(self::filter_check($level,$module_setting)==false)
		{
			return;
		}
		//------------------------
		$errno=0;
		$file = self::get_log_file($module_setting,$level);
		$sn = '['.DAO_Trace_Mark::curr().']';
		$trace_msg="";
		if($trace_layer>0&&isset($trace))
		{
			$trace_msg = self::get_trace($trace,$trace_layer);
		}
		$message=self::get_log_time($module_setting['fulldate']).' '.$sn.'['.get_client_ip().']'
		.'['.self::$levelnames[$level].']:'.$message;
		if(strlen($trace_msg) )
		{
			$message=rtrim($message);
			$message .= CRLF.'at:'.$trace_msg;
		}
		$message=rtrim($message);
		$message .=CRLF;
		//error_log($message,3,$file);

		file_put_contents($file,$message,FILE_APPEND);
		if ($errno == E_USER_ERROR) {
		}

		if($module_setting['stdout'])
		{
			print  trim($message)."\t\t\t($file)\r\n";
		}
	}

	public static function add_filter_allow($module,&$filter)
	{
		global $log_setting;
		$log_setting[$module]['allowfilter'][]=$filter;
	}
	
	public static function  check_allows(&$module_setting)
	{
		if(!is_array($module_setting['allowfilter']))
		{
			return ;
		}
		foreach($module_setting['allowfilter'] as $key=>$value)
		{
			if(is_object($value))
			{
				if($value->check()==true)
				{
					return true;
				}
			}
		}
		return false;
	}
	
	public static function  filter_check($level_to_log,&$module_setting)
	{
		if(self::check_allows($module_setting)==true)
		{
			return true;
		}
		if($module_setting["level"]>=$level_to_log)
		{
			return true;
		}
		return false;
	}
	
	public static function debug($message,$module='',$trace_layer=0)
	{
		if($trace_layer>0)
		{
			$trace=debug_backtrace();
			array_shift ($trace);
		}
		$level =4;
		self::log_implement($level,$message,$module,$trace,$trace_layer);
	}

	public static function info($message,$module='',$trace_layer=0)
	{
		$level=2;
		if($trace_layer>0)
		{
			$trace=debug_backtrace();
			array_shift ($trace);
		}
		self::log_implement($level,$message,$module,$trace,$trace_layer);
	}

	public static function error($message,$module='',$trace_layer=6)
	{
		if($trace_layer>0)
		{
			$trace=debug_backtrace();
			array_shift ($trace);
		}
		$level=1;
		self::log_implement($level,$message,$module,$trace,$trace_layer);
		self::debug($message,$module,$trace_layer);
	}

	public static function parse_line(&$line,&$out)
	{
		//找到第一个冒号
		$out['line'] = $line;
		$content_pre=']: ';
		$colonpos = strpos($line,$content_pre);
		if($colonpos===false)
		{
			$out['result']=-1;
			return ;
		}
		$header_string = substr($line,0,$colonpos);
		$out['content'] = substr($line,$colonpos+3);
		$blankpos = strpos($header_string," ");
		if($blankpos===false)
		{
			$out['result']=-2;
			return ;
		}
		$out['time'] = substr($header_string,0,$blankpos);
		$info_string = substr($header_string,$blankpos+1);
		$info_array = split(']',$info_string);
		$out['seq'] =trim( $info_array[0],'[');
		$out['ip'] =trim( $info_array[1],'[');
		$out['level'] =trim( $info_array[2],'[');
		$out['result']=0;
	}


	public static function read_file($filename,$line_handle,$max_line=0)
	{
		if(!function_exists($line_handle))
		{
			return ;
		}
		$fp = fopen($filename,'r');
		if($fp===false)
		{
			return ;
		}
		$i = 0;
		while(!feof($fp))
		{
			$line='';
			$out=array();
			$line = fgets($fp);
			if(strlen($line)==0)
			{
				continue;
			}
			DAO_Log::parse_line($line,$out);
			$out['index']=$i;
			$line_handle($out);
			$i++;
			if($max_line>0)
			{
				if($i>=$max_line)
				break;
			}
		}
		fclose($fp);
	}
};



function ut_log()
{
	DAO_Log::debug('test','bo');
	DAO_Log::error('error','bo');

}

?>